﻿/* **************************************************************************
 *
 * Copyright 2007-2010 Jeff Hardy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * *************************************************************************/

using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Client.Win32;

namespace NWSGI.ManagementClient
{
    internal class PythonPathsPage : ModuleListPage, IModuleChildPage
    {
        private ColumnHeader pathColumnHeader;

        private IModulePage parentPage;
        public IModulePage ParentPage
        {
            get { return this.parentPage; }
            set { this.parentPage = (ModulePage)value; }
        }
        
        private NwsgiModuleServiceProxy _serviceProxy;
        private NwsgiModuleServiceProxy ServiceProxy
        {
            get
            {
                if(_serviceProxy == null)
                {
                    _serviceProxy = (NwsgiModuleServiceProxy)CreateProxy(typeof(NwsgiModuleServiceProxy));
                }
                return _serviceProxy;
            }
        }

        private PythonPathEntryItem SelectedItem
        {
            get { return ListView.SelectedItems.Count > 0 ? (PythonPathEntryItem)ListView.SelectedItems[0] : null; }
        }

        private PythonPathsPage.PageTaskList taskList;
        protected override TaskListCollection Tasks
        {
            get
            {
                if(this.taskList == null)
                {
                    this.taskList = new PythonPathsPage.PageTaskList(this);
                }

                TaskListCollection col = base.Tasks;
                col.Add(this.taskList);
                return col;
            }
        }

        protected override void InitializeListPage()
        {
            pathColumnHeader = new ColumnHeader();
            pathColumnHeader.Text = "Path";
            pathColumnHeader.Width = -2;

            ListView.Columns.Add(pathColumnHeader);

            ListView.LabelEdit = true;
            ListView.MultiSelect = false;

            ListView.AfterLabelEdit += OnListViewAfterLabelEdit;
            ListView.ItemActivate += OnListViewItemActivate;
            ListView.SelectedIndexChanged += OnListViewSelectedIndexChanged;
            ListView.KeyUp += OnListViewKeyUp;
        }

        protected override void OnActivated(bool initialActivation)
        {
            base.OnActivated(initialActivation);
            if(initialActivation)
            {
                StartAsyncTask("Getting Python Paths...", new DoWorkEventHandler(GetPythonPaths),
                                              new RunWorkerCompletedEventHandler(GetPythonPathsCompleted));
            }
        }

        protected override bool CanRefresh
        {
            get { return !base.InProgress; }
        }

        protected override void Refresh()
        {
            StartAsyncTask("Getting Python Paths...", new DoWorkEventHandler(GetPythonPaths),
                                              new RunWorkerCompletedEventHandler(GetPythonPathsCompleted));
        }

        internal void GoBack()
        {
            base.Navigate(typeof(NwsgiPage));
        }

        private void GetPythonPaths(object sender, DoWorkEventArgs e)
        {
            e.Result = ServiceProxy.GetPythonPaths();
        }

        private void GetPythonPathsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ListView.BeginUpdate();
            ListView.Items.Clear();
            try
            {
                ArrayList paths = (ArrayList)e.Result;
                foreach(string path in paths)
                {
                    ListView.Items.Add(new PythonPathEntryItem(path));
                }
            }
            finally
            {
                ListView.EndUpdate();
            }
        }

        private void OnListViewSelectedIndexChanged(object sender, EventArgs e)
        {
            base.Update();
        }

        private void OnListViewKeyUp(object sender, KeyEventArgs e)
        {
            if(this.SelectedItem != null && e.KeyData == Keys.Delete)
                this.DeletePath();
        }

        private void OnListViewItemActivate(object sender, EventArgs e)
        {
            if(this.SelectedItem != null)
            {
                this.EditPath();
            }
        }

        private void OnListViewAfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            e.CancelEdit = true;

            if(e.Label != null)
            {
                PythonPathEntryItem item = (PythonPathEntryItem)base.ListView.Items[e.Item];
                string oldPath = item.Path, newPath = e.Label.Trim();

                if(newPath != oldPath && newPath.Length > 0)
                {
                    try
                    {
                        Cursor.Current = Cursors.WaitCursor;
                        
                        if(oldPath.Length == 0)
                            this.ServiceProxy.AddPythonPath(newPath);
                        else
                            this.ServiceProxy.EditPythonPath(oldPath, newPath);
                        
                        item.Path = newPath;
                        e.CancelEdit = false;
                    }
                    catch(Exception exception)
                    {
                        base.DisplayErrorMessage("An error occurred:", exception.Message);
                    }
                    finally
                    {
                        Cursor.Current = Cursors.Default;
                    }
                }
            }

            Refresh();
            Update();
        }

        internal void AddPath()
        {
            ListViewItem newPath = null;
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                newPath = ListView.Items.Add(new PythonPathEntryItem(""));
            }
            catch(Exception exception)
            {
                base.DisplayErrorMessage("An error occurred:", exception.Message);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

            if(newPath != null)
                newPath.BeginEdit();
        }

        internal void EditPath()
        {
            this.SelectedItem.BeginEdit();
        }

        internal void DeletePath()
        {
            if(this.SelectedItem != null && base.ShowMessage("Are you show you want to remove this path?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
            {
                try
                {
                    Cursor.Current = Cursors.WaitCursor;
                    this.ServiceProxy.DeletePythonPath(this.SelectedItem.Path);
                    base.ListView.Items.Remove(this.SelectedItem);
                }
                catch(Exception exception)
                {
                    base.DisplayErrorMessage("An error occurred:", exception.Message);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        private sealed class PythonPathEntryItem : ListViewItem
        {
            private string path;

            public PythonPathEntryItem(string path) : base(path, 0)
            {
                this.path = path;
            }

            public string Path
            {
                get { return path; }
                set { path = value; }
            }
        }

        private sealed class PageTaskList : TaskList
        {
            private PythonPathsPage owner;

            public PageTaskList(PythonPathsPage owner)
            {
                this.owner = owner;
            }

            public override ICollection GetTaskItems()
            {
                ArrayList list = new ArrayList();

                list.Add(new MethodTaskItem("AddPath", "Add...", "Actions"));

                PythonPathEntryItem selected = this.owner.SelectedItem;
                if(selected != null)
                {
                    list.Add(new MethodTaskItem("EditPath", "Edit", "Actions"));
                    list.Add(new MethodTaskItem("DeletePath", "Remove", "Actions"));
                }

                list.Add(new MethodTaskItem("GoBack", "Go Back", "Tasks", "Go back to the parent page"));

                return list;
            }

            public void AddPath()
            {
                this.owner.AddPath();
            }

            public void EditPath()
            {
                this.owner.EditPath();
            }

            public void DeletePath()
            {
                this.owner.DeletePath();
            }

            public void GoBack()
            {
                this.owner.GoBack();
            }
        }
    }
}
